/**
 *@Time    : 2021/11/9 22:06
 *@Author  : Shuai Jhou
 *@File    : main
 *@Software: GoLand
 * grpcurl -plaintext -d '{"name":"Redis"}' localhost:8001 proto.TagService.GetTagList
 */

package main

import (
	"context"
	"flag"
	pb "go.zhoushuai.cn/go-programming-tour-book/tag-service/proto"
	"go.zhoushuai.cn/go-programming-tour-book/tag-service/server"
	"google.golang.org/grpc"
	"google.golang.org/grpc/reflection"
	"log"
	"net"
	"net/http"
	"os"
	"os/signal"
	"time"
)

var grpcPort string
var httpPort string

func init() {
	flag.StringVar(&grpcPort, "grpc_port", "8001", "gRPC 启动端口")
	flag.StringVar(&httpPort, "http_port", "9001", "HTTP 启动端口号")
	flag.Parse()
}

func RunHttpServer(port string, stop <-chan struct{}) error {
	serverMux := http.NewServeMux()
	serverMux.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) {
		_, _ = w.Write([]byte("pong"))
	})
	s := &http.Server{Addr: ":" + port, Handler: serverMux}
	go func() {
		<-stop
		// Wait for interrupt signal to gracefully shut down the server with
		// a timeout of 5 seconds.
		// 最大时间控制，通知该服务端它有5s的时间来处理原来的请求
		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
		defer cancel()
		_ = s.Shutdown(ctx)
	}()
	return s.ListenAndServe()
}

func RunGrpcServer(port string, stop <-chan struct{}) error {
	s := grpc.NewServer()
	pb.RegisterTagServiceServer(s, server.NewTagServer())
	reflection.Register(s)
	lis, err := net.Listen("tcp", ":"+port)
	if err != nil {
		return err
	}
	go func() {
		<-stop
		s.Stop()
	}()
	return s.Serve(lis)
}

// grpcurl -plaintext localhost:8001 proto.TagService.GetTagList
// curl http://127.0.0.1:9001/ping
func main() {
	// 等待中断信号
	quit := make(chan os.Signal)
	// 接收syscall.SIGINT syscall.SIGTERM信号
	//signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM,syscall.SIGHUP)
	signal.Notify(quit, os.Interrupt)
	done := make(chan error, 2)
	stop := make(chan struct{})
	go func() {
		log.Printf("Http Server Port:%v \n", httpPort)
		err := RunHttpServer(httpPort, stop)
		if err != nil {
			done <- err
		}
	}()
	go func() {
		log.Printf("Grpc Server Port:%v \n", grpcPort)
		err := RunGrpcServer(grpcPort, stop)
		if err != nil {
			done <- err
		}
	}()
	select {
	case err := <-done:
		close(stop)
		log.Fatalf("[Stopped]Run Server err: %v", err)
	case <-quit:
		close(stop)
		log.Println("Shutdown server...")
	}
}
